package com.mmg.cosplay.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mmg.cosplay.entity.dto.LoginRequest;
import com.mmg.cosplay.entity.dto.LoginResponse;
import com.mmg.cosplay.entity.ChatMessages;
import com.mmg.cosplay.entity.User;
import com.mmg.cosplay.entity.po.RolePreset;
import com.mmg.cosplay.mapper.UserMapper;
import com.mmg.cosplay.service.IRolePresetService;
import com.mmg.cosplay.service.UserService;
import com.mmg.cosplay.utils.TimestampUtils;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ChatMessageDeserializer;
import dev.langchain4j.data.message.UserMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RequiredArgsConstructor
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    private final MongoTemplate mongoTemplate;

    private final IRolePresetService rolePresetService;

    @Override
    public List<Map<String,String>> getUserChatConversations(Long loginId) {
        // 查询所有以 requireId 开头的对话集合
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(loginId));
        List<ChatMessages> strings = mongoTemplate.find(query, ChatMessages.class);
        List<RolePreset> roles = rolePresetService.list();
        List<Map<String, String>> list = new ArrayList<>(strings.stream().map(item -> {
            // 获取角色信息
            String roleId = item.getRoleId().toString();
            String roleName = roles.stream().filter(role-> role.getId().toString()
                    .equals(roleId)).map(RolePreset::getRoleName).findFirst().orElse("默认角色");
            return Map.of("id", item.getMemoryId(),
                    "title", item.getTitle(),
                    "roleId", item.getRoleId().toString(), "roleName", roleName,
                    "time", item.getTime(),
                    "timestamp", String.valueOf(item.getTimestamp()),
                    "isTop", item.getIsTop() != null ? item.getIsTop() : "0");
        }).toList());
        // list里面的map，先按isTop降序排序（置顶的在前），再按timestamp降序排序
        list.sort((a, b) -> {
            String isTopA = a.get("isTop");
            String isTopB = b.get("isTop");
            // 先比较置顶状态
            int topCompare = isTopB.compareTo(isTopA);
            if (topCompare != 0) {
                return topCompare;
            }
            // 置顶状态相同时，按时间戳降序排序
            return b.get("timestamp").compareTo(a.get("timestamp"));
        });
        return list;
    }

    @Override
    public LoginResponse login(LoginRequest request) {
        User account = getAccountByUsername(request.getUsername());

        if (account == null) {
            throw new RuntimeException("用户不存在");
        }

        if (!passwordEncoder.matches(request.getPassword(), account.getPassword())) {
            throw new RuntimeException("密码错误");
        }

        // 登录成功，生成token
        StpUtil.login(account.getId());
        String token = StpUtil.getTokenValue();

        return new LoginResponse(token, account.getId(), account.getUsername(),
                account.getEmail());
    }

    @Override
    public Boolean saveUser(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return this.save(user);
    }

    @Override
    public Boolean updateUser(User user) {
        // 当加密的密码一致时不修改密码
        User existingUser = this.getById(user.getId());
        if (StringUtils.hasLength(user.getPassword())){
            if (!passwordEncoder.matches(existingUser.getPassword(), user.getPassword())) {
                user.setPassword(passwordEncoder.encode(user.getPassword()));
            }
        }else{
            user.setPassword(null);
        }
        // 修改
        return this.updateById(user);
    }

    @Override
    public User getAccountByUsername(String username) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        return this.getOne(wrapper);
    }

    @Override
    public List<ChatMessage> getMessagesByConversationId(String id) {
        Criteria criteria = Criteria.where("memoryId").is(id);
        Query query = new Query(criteria);
        ChatMessages chatMessages = mongoTemplate.findOne(query, ChatMessages.class);
        if (chatMessages == null) {
            return List.of();
        }
        String contentJson = chatMessages.getContent();
        return ChatMessageDeserializer.messagesFromJson(contentJson);
    }

    @Override
    public Boolean renameConversation(String memoryId, String newTitle) {
        try {
            // 验证当前用户是否有权限修改该会话
            Long currentUserId = Long.parseLong(StpUtil.getLoginId().toString());
            Criteria criteria = Criteria.where("memoryId").is(memoryId)
                    .and("userId").is(currentUserId);
            Query query = new Query(criteria);
            
            Update update = new Update();
            update.set("title", newTitle);
            
            return mongoTemplate.updateFirst(query, update, ChatMessages.class).getModifiedCount() > 0;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public Boolean deleteConversation(String memoryId) {
        try {
            // 验证当前用户是否有权限删除该会话
            Long currentUserId = Long.parseLong(StpUtil.getLoginId().toString());
            Criteria criteria = Criteria.where("memoryId").is(memoryId)
                    .and("userId").is(currentUserId);
            Query query = new Query(criteria);
            
            return mongoTemplate.remove(query, ChatMessages.class).getDeletedCount() > 0;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public Boolean toggleConversationTop(String memoryId, String isTop) {
        try {
            // 验证当前用户是否有权限修改该会话
            Long currentUserId = Long.parseLong(StpUtil.getLoginId().toString());
            Criteria criteria = Criteria.where("memoryId").is(memoryId)
                    .and("userId").is(currentUserId);
            Query query = new Query(criteria);
            
            Update update = new Update();
            update.set("isTop", isTop);
            
            return mongoTemplate.updateFirst(query, update, ChatMessages.class).getModifiedCount() > 0;
        } catch (Exception e) {
            return false;
        }
    }
}
